
/*
 * zoj 3511 . Cake Robbery
 * 题目网址： https://zoj.pintia.cn/problem-sets/91827364500/problems/91827368875
 * 线段树 说明
 * seg_data_type： 线段树维护的信息的数据类型
 * OP_TYPE: 区间操作类型
 * NODE_DATA: 节点存储数据的类型
 * SegNode::data_init 节点数据初始化
 * SegNode::leaf_init 叶子节点数据初始化
 * SegNode::push_down [l,r]区间维护的数据往下分配给子节点
 * SegNode::push_up 据子节点的信息更新区间[l,r]维护的信息
 * SegNode::query 查询或更新子树
 * SegNode::merge_val 合并从子树查询到的结果
 * SegNode::output 输出节点,调试用
 * SegTree::start_pos 区间起始位置0或者1
 * SegTree::seg_query_init_val 查询区间的初始值,例如区间求和为0，区间求乘积为1
 * SegTree::leaf_default_val 叶子节点默认值(如果传给SegTree::init_tree的data为NULL则需要设置leaf_default_val)
 */

#include <stdio.h>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;


typedef int seg_data_type; 

enum OP_TYPE{
	OP_DEL_ALL = 1, 	//删除所有
	OP_GET_SUM = 2, 	//获取总和
};

enum NODE_DATA{
	SUM, 	//顶点总和
	NODE_DATA_NUM
};

class SegTree;
class SegNode{
	friend SegTree;
private:
	seg_data_type 		data[NODE_DATA_NUM];
	SegNode * 			children[2]; 	//子节点
	int l; 				//区间左边界
	int r; 				//区间右边界
public:

	void data_init(){
		data[SUM] = 1;
	}

	void leaf_init(seg_data_type d){
		data[SUM] = d;
	}

	void push_down(){
		if(data[SUM] == 0){
			//父节点已经清空则子节点也要清空
			children[0]->data[SUM] = children[1]->data[SUM] = 0;
		}
	}

	//根据子节点的信息更新信息
	void push_up(){
		data[SUM] = children[0]->data[SUM] + children[1]->data[SUM];
	}

	
	seg_data_type query(int op, int k){
		seg_data_type v = 0;
		// 更新节点
		if(op == OP_DEL_ALL){
			data[SUM] = 0;
		}else if(op == OP_GET_SUM){
			v = data[SUM];
		}
		return v;
	}
	
	void merge_val(int op, seg_data_type& val, seg_data_type sub_tree_val){
		if(op == OP_GET_SUM){
			val += sub_tree_val;
		}
	}

	void output(){
		printf("[%d,%d] data[SUM]=%ld\n", l, r, data[SUM]);
	}

	SegNode(){
		init();
	}

	void init(){
		l = r = 0;
		children[0] = children[1] = NULL;
		data_init();
	}

	bool is_leaf(){
		return l == r;
	}

	bool not_leaf(){
		return !is_leaf();
	}

	//判断线段的区间是否完全在区间[l, r]里
	bool inside(int l, int r){
		return l <= this->l && this->r <= r;
	}

	//判断线段的区间是否和区间[l, r]完全不相交
	bool no_intersect(int l, int r){
		return this->r < l || r < this->l;
	}

	bool intersect(int l, int r){
		return !no_intersect(l, r);
	}

	int len(){
		return r - l + 1;
	}
	
	//中点
	int mid(){
		return (l + r) >> 1;
	}

};

class SegTree{
private:
	int 			start_pos;  			//区间起始位置，0或者1
	seg_data_type 	seg_query_init_val;  	//查询区间的初始值
	seg_data_type 	leaf_default_val;  		//叶子节点默认值
	vector<SegNode> tree;
	int node_num; 	//节点个数
public:
	SegTree(int init_num){
		start_pos = 1;
		seg_query_init_val = 0;
		leaf_default_val = 1;
		tree.resize(init_num);
	}

	//初始化线段树
	void init_tree(int *data, int n){
		//线段树节点的个数为2*-1
		if(2 * n - 1 > tree.size()){
			tree.resize(2 * n - 1);
		}
		node_num = 0;
		init_seg(&tree[node_num++], data, n, start_pos, n - 1 + start_pos);
	}

	//初始化区间
	void init_seg(SegNode *node, int *data, int n, int l, int r){
		node->init();
		node->l = l;
		node->r = r;
		if(l == r){
			if(data != NULL){
				node->leaf_init(data[l - start_pos]);
			}else{
				node->leaf_init(leaf_default_val);
			}
		}else{
			int mid = node->mid();
			for(int i = 0; i < 2; i ++){
				node->children[i] = &tree[node_num++];
			}
			// mid属于左子树
			init_seg(node->children[0], data, n, l, mid);
			init_seg(node->children[1], data, n, mid + 1, r);
			node->push_up();
		}
	}

	SegNode* root(){
		return &tree[0];
	}


	seg_data_type query_tree(int op, int l, int r){
		return query(root(), op, l, r, 0);
	}

	seg_data_type query_tree(int op, int l, int r, int k){
		return query(root(), op, l, r, k);
	}

	seg_data_type query(SegNode *node, int op, int l, int r, int k){
		seg_data_type v = seg_query_init_val;
		if(node->inside(l, r)){
			v = node->query(op, k);
		}else if(node->not_leaf() && node->intersect(l, r)){
			node->push_down();
			//区间相交往下降 
			int mid = node->mid();
			if(l <= mid){
				node->merge_val(op, v, query(node->children[0], op, l, min(mid, r), k));
			}
			if(r > mid){
				node->merge_val(op, v, query(node->children[1], op, max(mid + 1, l), r, k));
			}
			node->push_up();
		}
		return v;
	}

	void output(){
		for(int i = 0; i < node_num; i++){
			tree[i].output();
		}
	}

};

typedef pair<int, pair<int, int> > op_pair;

bool op_pair_cmp(op_pair a, op_pair b){
	return (a.first == b.first && a.second.first <  b.second.first) || a.first < b.first;
}

int main(int argc, char* argv[])
{
	const int NUM = 10000;
	op_pair ops[NUM];
	int n;
	//构建线段树
	SegTree seg_tree(2 * NUM);
	//线段树初始化
	/*
	seg_tree.init_tree(data, n);
	seg_tree.query_tree(1, 1, 5, 2);
	cout << "sum[1,1]=" << seg_tree.query_tree(2, 1, 1, 0) << endl;
	*/
	int m, x, y, l, r, max_len, len;
	while(scanf("%d%d", &n, &m) != EOF){
		seg_tree.init_tree(NULL, n);
		for(int i = 0; i < m; i++){
			scanf("%d%d", &x, &y);
			if(x > y){
				swap(x, y);
			}
			ops[i].first = y - x + 1;
			ops[i].second.first = x;
			ops[i].second.second = y;
		}
		sort(ops, ops + m, op_pair_cmp);
		max_len = 0;
		for(int i = 0; i < m; i++){
			l = ops[i].second.first;
			r = ops[i].second.second;
			len = seg_tree.query_tree(OP_GET_SUM, l, r);
			if(max_len < len){
				max_len = len;
			}
			l++;
			r--;
			//抹去中间的点
			if(l <= r){
				seg_tree.query_tree(OP_DEL_ALL, l, r);
			}
		}
		len = seg_tree.query_tree(OP_GET_SUM, 1, n);
		if(max_len < len){
			max_len = len;
		}
		printf("%d\n", max_len);
	}
    return 0;
}
